public without sharing class ImportObject {
    
     public ImportObject(ApexPages.StandardController con){
        
     }

     public ImportObject(Object controller){}

    
    public static Set<String>  getCateOrBrandFromProduct(String target , String condition ){

        String sql = 'select '+ target + ' from Product__c  where ' + target +' != null ';
        Map<String,Object> conMap = (Map<String,Object>) JSON.deserializeUntyped(condition);
        if(conMap.keySet().size() > 0){
            for (String k  : conMap.keySet() ) {
                sql += ' and ' + k + ' = \''+String.valueOf(conMap.get(k))+'\' ';
            }
        }
        sql += ' group by '+ target;
        Set<String> resSet = new Set<String>();
        for(AggregateResult agg :Database.query(sql)){
            resSet.add(String.valueOf(agg.get(target)));
        }
        return resSet;
    }
    @RemoteAction
    public static Map<String ,Object> query(String sql   ){

        Map<String,Object> tmp= new Map<String,Object>();
        tmp.put('data', Database.query(sql)) ;
        tmp.put('size', Database.countQuery(sql.replaceFirst('select.*from','select count() from ').replaceFirst('order by.*',' ') ));
        return tmp;

    }

     @RemoteAction
    public static Map<String ,Object> queryMore(String sql,String tagId  ){

        Map<String,Object> tmp= new Map<String,Object>();
        tmp.put('size', Database.countQuery(sql.replaceFirst('select.*from','select count() from ').replaceFirst('order by.*',' ') ));
        if(tagId != null && tagId.trim().length() >0 ) sql = sql.replace('order by', ' and Id > \''+tagId+'\' order by ');
        tmp.put('data', Database.query(sql)) ;
        return tmp;

    }
    /*
    @RemoteAction
    public static Map<String ,Object> query(String sql,String objName ,String orderby, String limitno  ,Integer idx ){

        Map<String,Object> tmp= new Map<String,Object>();
        tmp.put('size', Database.countQuery(sql.replaceFirst('select.*from','select count() from ').replaceFirst('order by.*',' ') ));
        if(idx == null || idx == 0  ){

            tmp.put('data', Database.query(sql + orderby+limitno )) ;

        }else{
           String startId =  getOffsetId(objName,orderby, idx );
           if(sql.contains('where')){

             sql += ' and  Id > \''+startId+'\' ' + orderby + limitno;

           }else{

             sql += ' where Id > \''+startId+'\' ' + orderby + limitno ;

           }
             tmp.put('data', Database.query(sql)) ;


        }

        return tmp;
    }
    @RemoteAction
    public static String getOffsetId(String objName,String orderby  , Integer offset){

        if(offset <= 2002 ){
            if(offset <= 1) return  Database.query(' select Id from '+ objName  + orderby +'  limit 1 ').Id ;
            return  Database.query(' select Id from '+ objName  + orderby +'  limit 1  offset '+ (offset -2 ) ).Id ;
        }else{
            String startId = '';
            Integer ofs =  offset  ;
            Integer totals = ofs/ 2000 ;
            Integer mo = Math.mod(ofs,2000);
            for(Integer i = 0 ; i < totals ; i ++){
                if(startId == null || startId.trim().length() == 0 ){
                    Database.QueryLocator
                    startId = Database.query(' select Id from '+ objName  + orderby +' limit 1 offset 1998 ' ).Id ;
                }else{
                    startId = Database.query(' select Id from '+ objName + ' where Id >\''+startId+'\' ' + orderby +' limit 1 offset 1999 ' ).Id ;

                }
            }
            if(mo == 0 ) return startId;
            return Database.query(' select Id from '+ objName + ' where Id >=\''+startId+'\' ' + orderby +' limit 1 offset  '+mo   ).Id ;
        }
    }*/
     public static Set<Id> getSubRoleSet(Set<Id> roles ){
        Set<Id> totals = new Set<Id>();
        totals.addAll(roles);
        Set<Id> roleset = new Set<Id>();
        for(UserRole ur :[select Id,Name  from UserRole where ParentRoleId in:roles]){
            roleset.add(ur.Id);
            totals.add(ur.Id);
        }
        while(roleset.size() > 0){
            Set<Id> tmp = new Set<Id>();
            tmp.addAll(roleset);
            roleset.clear();

            for(UserRole ur :[select Id,Name from UserRole where ParentRoleId in:tmp]){
                roleset.add(ur.Id);
                totals.add(ur.Id);
            }

        }
        return totals;  


     }
    
     

    @RemoteAction 
    public static String deleteImport(String ims ){

        List<Object> ids  = (List<Object>)JSON.deserializeUntyped(EncodingUtil.urlDecode(ims, 'UTF-8')) ;
        List<String> ids1 = new  List<String>();
        for (Object o  : ids ) {
            ids1.add(String.valueOf(o));
        }
        SavePoint sp = Database.setSavepoint();
        if(ids.isEmpty())return '没有数据!';
        try {
            delete  [select Id from TaskTrackingDetailImport__c where TaskTrackingImport__c in: ids1 ];
            delete  [select Id from TaskTrackingImport__c where Id in: ids1 ];
            return '操作成功!';
        }
        catch (Exception e) {
            Database.rollback(sp);
            return '操作失败:'+e.getMessage();
        }
        
    }
    /*
    * 获取没有拆分的 手工导入的任务量信息
    */
    @RemoteAction
    public static String getTaskImport(){
        List<Map<String,String>> datas = new List<Map<String,String>>();
        //
        Map<String,String>  comMap  = getPicklistValues('TaskTrackingImport__c','Company__c', true );
        for(TaskTrackingImport__c tt :[select Id ,Instrumentstartdate__c  , Enddateofinstrument__c,TaskSource__c,
            OwnerCompany__c,OwnerYM__c,Company__c,MCode__c,Outgoingway__c,EnterWay__c,
            OutgoingNumber__c,InstrumentType__c,SerialNo__c,Numberofyears__c,ContractYear__c,
            ContractStartDate__c,ContractEndDate__c,ContractNumber__c,OverallPackagingMode__c,Contract__c,
            CalculationTable__c,MKCooperationType__c,OutdoorDate__c,EstimateNumber__c,
            Account__r.Name , TerminalCustomer__r.Name ,InstrumentDeliveryCost__c,SubcompanyInstrumentDeliveryCost__c,
            InstrumentName__r.ProductName__c  ,IsSplited__c ,InstrumentName__r.NCCode__c,Tax__c,EquipNote__c,TaskDetailNote__c,
            (select Classification1__c, Classification2__c,ReagentBrand__c,GroupGrossProfit__c,SubCompanyGrossProfit__c,
             Years__c,WhetherNew__c,WhetherCovered__c,ReagentAssignments__c
             from TaskTrackingImport__r )
            from TaskTrackingImport__c where IsSplited__c =false  order by Mcode__c ]){
            Map<String,String> d = new Map<String,String>();
            d.put('sfid', tt.Id);
            d.put('owner_year_month',tt.OwnerYM__c  );
            d.put('owner_area', tt.OwnerCompany__c);
            d.put('sign_company',comMap.get(tt.Company__c ));
            d.put('sf_pay_account_id', tt.Account__r.Name );
            d.put('sf_ter_account_id',tt.TerminalCustomer__r.Name  );
            d.put('invname', tt.InstrumentName__r.ProductName__c);
            d.put('iemi', tt.SerialNo__c );         
            d.put('coop_start_date', tt.Instrumentstartdate__c.format());
            d.put('coop_end_date',tt.Enddateofinstrument__c.format() );

            d.put('nccode', tt.InstrumentName__r.NCCode__c);
            d.put('mcode',tt.MCode__c );
            d.put('outdoor_way',tt.Outgoingway__c );
            d.put('enter_way', tt.EnterWay__c);
            d.put('task_resource',tt.TaskSource__c );

            d.put('outdoor_no', tt.OutgoingNumber__c);
            d.put('invtype', tt.InstrumentType__c);
            d.put('coop_year', tt.Numberofyears__c);
            d.put('contract_year',tt.ContractYear__c );
            d.put('contract_start_date',tt.ContractStartDate__c == null ? '': tt.ContractStartDate__c.format() );
            d.put('contract_end_date', tt.ContractEndDate__c == null ? '': tt.ContractEndDate__c.format());
            d.put('contract_no', tt.ContractNumber__c);
            d.put('pack_way',tt.OverallPackagingMode__c);
            d.put('is_have_contract',tt.Contract__c);
            d.put('is_have_mc', tt.CalculationTable__c);
            d.put('coop_type', tt.MKCooperationType__c);
            d.put('outdoor_date',tt.OutdoorDate__c == null ? '': tt.OutdoorDate__c.format() );

            d.put('sf_mc_no', tt.EstimateNumber__c);
            d.put('sub_cost', String.valueOf(tt.SubcompanyInstrumentDeliveryCost__c));
            d.put('group_cost', String.valueOf(tt.InstrumentDeliveryCost__c));

           //d.put('is_trid_from_contract', tt.IsTridFromContract__c );
            d.put('detail_note', tt.TaskDetailNote__c);
            d.put('equip_note', tt.EquipNote__c);
            d.put('tax', String.valueOf(tt.Tax__c));
            for (TaskTrackingDetailImport__c ttdi  : tt.TaskTrackingImport__r ) {
                d.put('regent_cate1', ttdi.Classification1__c);
                d.put('regent_cate2', ttdi.Classification2__c);
                d.put('regent_brand', ttdi.ReagentBrand__c);
                d.put('is_need_add_task', ttdi.WhetherNew__c);
                d.put('is_need_replace_task', ttdi.WhetherCovered__c);
                d.put('assign_'+ttdi.Years__c, String.valueOf(ttdi.ReagentAssignments__c));
                d.put('sub_profit_'+ttdi.Years__c, String.valueOf(ttdi.SubCompanyGrossProfit__c));
                d.put('group_profit_'+ttdi.Years__c,String.valueOf(ttdi.GroupGrossProfit__c));

            }



            datas.add(d);
        }

        return EncodingUtil.urlEncode(JSON.serialize(datas), 'UTF-8') ;
    }
    /*
    *拆分手动导入的任务量
    */
    @RemoteAction
    public static String splitTaskFromImp(String taskId){
        Map<String,Object> resultMap = new Map<String,Object>();
        //1.查询导入的任务量主表
        TaskTrackingImport__c tti  = null ; 
        try{
            //AllMaccuraBrand__c,AllBrand__c
            //IsTridFromContract__c
            tti = [select Id ,Instrumentstartdate__c  , Enddateofinstrument__c,OwnerCompany__c,TaskSource__c,
                InstrumentName__r.ProductName__c,EnterWay__c,Numberofyears__c,EstimateNumber__c,
                ContractNumber__c,MCode__c,InstrumentType__c,Company__c,
            Account__c, TerminalCustomer__c,InstrumentDeliveryCost__c,SubcompanyInstrumentDeliveryCost__c,
            InstrumentName__c,SerialNo__c ,IsSplited__c ,CalculationTable__c ,OutdoorDate__c,OutgoingNumber__c,
            ContractStartDate__c,ContractEndDate__c,Outgoingway__c,EquipNote__c,TaskDetailNote__c,Tax__c


            ,(select Id , Years__c, ReagentAssignments__c , Classification1__c , GroupGrossProfit__c, 
                Classification2__c, ReagentBrand__c,SubCompanyGrossProfit__c , WhetherCovered__c 
                from tt.TaskTrackingImport__r where TaskTrackingImport__c =:taskId )

             from TaskTrackingImport__c tt  where Id=:taskId];

        }catch(Exception e){}
        if(tti == null )return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'任务量ID错误!')), 'UTF-8') ;

        if(tti.IsSplited__c)return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'该任务量已拆分,请不要重复拆分!')), 'UTF-8') ;

        //2.查询导入的任务量明细
        List<TaskTrackingDetailImport__c> ttList = tti.TaskTrackingImport__r;

        ///匹配公司
         Map<String ,String> comMap = new Map<String,String>();
        for(String com : Label.ShortCompanyName.split(',',-1)){
            List<String> cs = com.split('-',-1);
            if(cs != null && cs.size() > 1)comMap.put(cs[1],cs[0]);
        }
        comMap.put('东区','MKSW' );
        comMap.put('南区','MKSW' );
        comMap.put('西区','MKSW' );
        comMap.put('北区','MKSW' );
        comMap.put('中区','MKSW' );

        if(comMap.get(tti.OwnerCompany__c) == null )return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'所属公司未匹配到,请检查数据 : '+ tti.OwnerCompany__c +' 或 联系管理员维护子公司 Label.ShortCompanyName' )), 'UTF-8') ;
        //3.找到任务量追踪总表; 无则 新建任务量追踪总表
        CooperationStandard__c cs  = null ;
        try{
             cs =  [select Id ,Company__c ,EndingDate__c,StartingDate__c  from CooperationStandard__c  where NewData__c = true 
            and Account__c =:tti.Account__c and TerminalCustomer__c =:tti.TerminalCustomer__c limit  1 ]; 
            if(cs.EndingDate__c.daysBetween(tti.Enddateofinstrument__c) > 0)cs.EndingDate__c = tti.Enddateofinstrument__c;
            if(comMap.get(tti.OwnerCompany__c) == null) return   EncodingUtil.urlEncode(JSON.serialize(setResult(false,'导入的所属公司异常!')), 'UTF-8') ;
            if(cs.Company__c != null && cs.Company__c  != comMap.get(tti.OwnerCompany__c)) return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'导入的所属公司不一致!总表ID:'+cs.Id +'导入:'+tti.OwnerCompany__c +' 总表: '+cs.Company__c)), 'UTF-8') ;
            if(cs.Company__c == null)cs.Company__c =  comMap.get(tti.OwnerCompany__c) ;
            if(tti.Instrumentstartdate__c  != null && tti.Instrumentstartdate__c.daysBetween(cs.StartingDate__c) > 0 )cs.StartingDate__c = tti.Instrumentstartdate__c;
        }catch(Exception e){
            cs =  new CooperationStandard__c();
            cs.Account__c = tti.Account__c;//开票客户
            cs.TerminalCustomer__c = tti.TerminalCustomer__c;
            cs.NewData__c = true; //标记是新生成的任务量主表
            //cs.CSQuote__c = tti.CalculationTable__c;
            cs.Company__c = comMap.get(tti.OwnerCompany__c)  ;
            cs.StartingDate__c = tti.Instrumentstartdate__c;
            cs.EndingDate__c = tti.Enddateofinstrument__c;
           // cs.company__c = comMap.get(tti.OwnerCompany__c);

        }

        //4.拆分仪器 到追踪总表 下的仪器表
        TaskEquipment__c  te = null ;
        if( tti.InstrumentName__c  != null ){
            //4.1判断 投放仪器中是否存在此台仪器 ; 若存在,则报错
            if(cs.Id != null ){
               List<TaskEquipment__c>  teL = [select Id from TaskEquipment__c where Standers__c =:cs.Id  and 
               InstrumentName__c =:tti.InstrumentName__c and Mcode__c =: tti.MCode__c  and NewData__c = true  ];
              
               if(teL != null && teL.size() > 0) return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'仪器已存在任务量总表!总表ID:'+cs.Id + ' 仪器ID '+tti.InstrumentName__c + ' 识别码: '+ tti.Mcode__c )), 'UTF-8') ;

            }
            te = new TaskEquipment__c();
            te.NewData__c = true ;//标记为新的数据
            te.InstrumentName__c = tti.InstrumentName__c ;
            te.SerialNo__c = tti.SerialNo__c;//机身号
            te.SubcompanyInstrumentDeliveryCost__c = tti.SubcompanyInstrumentDeliveryCost__c;//子公司成本
            te.InstrumentDeliveryCost__c = tti.InstrumentDeliveryCost__c ;//集团成本
            te.OutdoorDate__c = tti.OutdoorDate__c ;//出库日期
            te.Contractnumber__c = tti.ContractNumber__c;//合同编号
            te.EnterWay__c = tti.EnterWay__c ; //进入方式
            te.OutgoingNumber__c = tti.OutgoingNumber__c;//出库单号
            te.Numberofyears__c = tti.Numberofyears__c; //合作年限
            te.Instrumentstartdate__c = tti.Instrumentstartdate__c ; //合作起算日期
            te.Enddateofinstrument__c = tti.Enddateofinstrument__c ;//合作截止日期

            te.TaskSource__c = tti.TaskSource__c;

            te.ProductName__c  = tti.InstrumentName__r.ProductName__c ;
            te.Model__c = tti.InstrumentType__c;//仪器规格/型号
            te.Outgoingway__c = tti.Outgoingway__c ;//仪器出库方式;

            te.ContractStartDate__c = tti.ContractStartDate__c;//合同开始
            te.ContractEndDate__c = tti.ContractEndDate__c;//合同结束
            te.MCode__c = tti.MCode__c;//导入识别码

            te.Pingpai__c  = ttList[0].ReagentBrand__c ; 
            te.FirstClass__c = ttList[0].Classification1__c ; 
            te.Twolevel__c = ttList[0].Classification2__c ; 
            //te.WhetherFromContract__c = tti.IsTridFromContract__c;
            te.Note__c = tti.EquipNote__c ; 


        }

        ///查找测算
        String mc_no = null;
        if(tti.EstimateNumber__c != null ){

            try {
               mc_no =  [select Id  from Measure_Calculate__c where name =: tti.EstimateNumber__c.trim() ].Id  ;
            }
            catch (Exception e) {
                //resultMap.put('code', '0');
                //resultMap.put('msg','测算编号不存在!'+tti.EstimateNumber__c  );
                return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'测算编号不存在!'+tti.EstimateNumber__c)), 'UTF-8') ; 
            }
            
        } 

        //5.拆分任务量 到追踪总表 下的任务量明细表 
        List<TaskAmount__c> tl  = new List<TaskAmount__c>();
        if(ttList.size() > 0){

            String stY =  String.valueOf(tti.Instrumentstartdate__c.year()) + '年';
            Set<String> stMs  = new Set<String>();
           for(Integer i = tti.Instrumentstartdate__c.month() ; i <=12 ; i ++){
                stMs.add(String.valueOf(i));
            }
            String enY =  String.valueOf(tti.Enddateofinstrument__c.year()) + '年';
            Set<String> enMs  = new Set<String>();
           for(Integer i =1 ; i <=tti.Enddateofinstrument__c.month()  ; i ++){
                enMs.add(String.valueOf(i));
            }
            Map<String ,TaskAmount__c > etMap = new Map<String,TaskAmount__c>();
            ///5.1 判断是否存在重复的
           /* if(cs.Id != null ){
              
               for(TaskAmount__c ta : [select Id,Year__c , AssignAmount__c , Category1__c , Category2__c, Brand__c , Month__c , SubProfit__c,GroupProfit__c,
                MeasureCalc__c, TaskTrackingDetailImport__c,Origin__c  from TaskAmount__c where Category1__c=:ttList[0].Classification1__c and   Category2__c =:ttList[0].Classification1__c and 
                Brand__c =:ttList[0].ReagentBrand__c and  IsAdjust__c = false and Standers__r.Account__c =:tti.Account__c  and Standers__r.TerminalCustomer__c =:tti.TerminalCustomer__c 
                and Origin__c != '销售政策'   
                and (Year__c >:stY Or (Year__c =:stY and Month__c in: stMs))
                and (Year__c >:enY Or (Year__c =:enY and Month__c in: enMs))   ]){
                   
                    String key =  ta.Category1__c +'_'+ta.Brand__c +'_'+ta.Category2__c + '_'+ta.Year__c + '_'+ ta.Month__c;

                    if(ta.Origin__c != '手工导入' ){
                        resultMap.put('code', '0');
                        resultMap.put('msg','投放任务量 存在非手工导入的重复任务量! '+tti.Id  );
                        return EncodingUtil.urlEncode(JSON.serialize(resultMap), 'UTF-8') ;
                    }
                    etMap.put(key,ta);

               }

            }*/


            Map<String ,TaskAmount__c > tMap = new Map<String,TaskAmount__c>();


            for(TaskTrackingDetailImport__c t :ttList){

                if(t.Years__c == String.valueOf(tti.Instrumentstartdate__c.year())){
                    for(String m  : stMs){
                       TaskAmount__c ta =  genTaskAmountFromTTImport(t,m,stMs.size(),tti ,mc_no);
                       String key =  ta.Category1__c +'_'+ta.Brand__c +'_'+ta.Category2__c + '_'+ta.Year__c + '_'+ ta.Month__c;
                        tMap.put(key,ta);
                    }
                }else if(t.Years__c == String.valueOf(tti.Enddateofinstrument__c.year())){
                    for(String m : enMs){
                        TaskAmount__c ta =  genTaskAmountFromTTImport(t,m,enMs.size(),tti,mc_no);
                        String key =  ta.Category1__c +'_'+ta.Brand__c +'_'+ta.Category2__c + '_'+ta.Year__c + '_'+ ta.Month__c;
                        tMap.put(key,ta);
                    }
                }else{
                    for(Integer i = 1 ; i <= 12 ; i ++){
                        TaskAmount__c ta =  genTaskAmountFromTTImport(t,String.valueOf(i),12,tti,mc_no);
                        String key =  ta.Category1__c +'_'+ta.Brand__c +'_'+ta.Category2__c + '_'+ta.Year__c + '_'+ ta.Month__c;
                        tMap.put(key,ta);
                    }
                }
            }

            for(String k :tMap.keySet() ){

                //TaskAmount__c oldta = etMap.get(k);
                TaskAmount__c ta = tMap.get(k);

                /*if(oldta != null ) {
                    ta.AssignAmount__c = ttList[0].WhetherCovered__c == '是' ? ta.AssignAmount__c : ta.AssignAmount__c + oldta.AssignAmount__c ;
                    ta.SubProfit__c = ttList[0].WhetherCovered__c == '是' ? ta.SubProfit__c : ta.SubProfit__c + oldta.SubProfit__c ;
                    ta.GroupProfit__c = ttList[0].WhetherCovered__c == '是' ? ta.GroupProfit__c : ta.GroupProfit__c + oldta.GroupProfit__c ;
                    ta.Id = oldta.Id  ; 
                }*/

                tl.add(ta);

            }

        }
        SavePoint sp = Database.setSavepoint();
        try {
            //保存 总表
            upsert cs; 
            //保存 投放仪器
           if(te !=  null ){
                te.Standers__c = cs.Id;
                upsert te;
           } 
           ///保存 任务量
            for(TaskAmount__c t : tl){
                t.Standers__c = cs.Id; 
            }
            System.debug(tl);
            if(tl.size() > 0)upsert tl;

            ///更新 标记
            tti.IsSplited__c = true ; 
            update tti;

            //resultMap.put('code', '1');
            //resultMap.put('msg','保存成功!' );
            return EncodingUtil.urlEncode(JSON.serialize(setResult(true,'保存成功!')), 'UTF-8') ;
        }catch (Exception e) {
            
            Database.rollback(sp);
           // resultMap.put('code', '0');
            //resultMap.put('msg','保存失败'+e.getCause() + '  '+e.getStackTraceString() );
            return EncodingUtil.urlEncode(JSON.serialize(setResult(false,'保存失败'+e.getCause() + '  '+e.getStackTraceString())), 'UTF-8') ;
        }

    }

    private static TaskAmount__c genTaskAmountFromTTImport(TaskTrackingDetailImport__c t,String m  , Integer siz ,TaskTrackingImport__c tti ,String mc_no ){

        TaskAmount__c ta = new TaskAmount__c();
        ta.MCode__c = tti.MCode__c;//
        ta.Category1__c = t.Classification1__c;
        ta.Category2__c = t.Classification2__c;
        ta.Brand__c = t.ReagentBrand__c;
        ta.Month__c = m ;
        ta.Year__c = t.Years__c+'年';
        ta.MeasureCalc__c = mc_no ;
        ta.CalculationTable__c = tti.CalculationTable__c;

        ta.Contractnumber__c = tti.ContractNumber__c;
        ta.AssignAmount__c = t.ReagentAssignments__c == null ? null : t.ReagentAssignments__c / siz ;
        ta.SubProfit__c = t.SubCompanyGrossProfit__c == null ?  null : t.SubCompanyGrossProfit__c / siz ;
        ta.GroupProfit__c = t.GroupGrossProfit__c == null ? null : t.GroupGrossProfit__c / siz ;  
       // ta.Cost__c = t.ReagentAssignments__c == null || t.SubCompanyGrossProfit__c == null ? null :(t.ReagentAssignments__c - t.SubCompanyGrossProfit__c ) / siz;
        ta.TaskTrackingDetailImport__c = t.Id;
        ta.TaskSource__c = tti.TaskSource__c;
        ta.Note__c = tti.TaskDetailNote__c;
        ta.Tax__c = tti.Tax__c;
        //ta.WhetherFromContract__c = tti.IsTridFromContract__c;
       //ta.AllMaccuraBrand__c = tti.AllMaccuraBrand__c;
        //ta.AllBrand__c = tti.AllBrand__c;
        ta.Origin__c = '手工导入';

        return ta;
    }

    private static Map<String,Object> setResult(Boolean issuc ,String msg  ){
       Map<String,Object> resultMap = new Map<String,Object>();

       resultMap.put('code', issuc ? '1': '0');
        resultMap.put('msg', msg);
        return resultMap;

    }
    //手动导入的任务量保存
    @RemoteAction 
    public static String importTask(String dataJson){

        Map<String,Object> resultMap = new Map<String,Object>();
        List<Object> cList = (List<Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(dataJson, 'UTF-8'));

        Map<String,String> prodMap = new Map<String,String>();
        Map<String,String> prodNameMap = new Map<String,String>();
        Map<String,TaskTrackingImport__c> ttiMap = new Map<String,TaskTrackingImport__c>();
        Map<String,String> mcodeMap = new Map<String,String>();
        List<Object> errList = new List<Object>();
        for(Object o :cList ){
            Map<String,Object> mo = (Map<String,Object>)o;
            mcodeMap.put(getStringValue(mo.get('mcode')), null);
            String nccode = getStringValue(mo.get('nccode'));
            String onlykey = getTTAccountID(getStringValue(mo.get('sf_ter_account_id')))
                            +getTTAccountID(getStringValue(mo.get('sf_pay_account_id')))
                            +getStringValue(mo.get('owner_area'))
                            +getStringValue(mo.get('owner_year_month'))
                            +getStringValue(mo.get('sign_company'))
                            +getStringValue(mo.get('regent_brand'))
                            +getStringValue(mo.get('regent_cate1'))
                            +getStringValue(mo.get('regent_cate2'))
                            +getStringValue(mo.get('nccode'))
                            +getStringValue(mo.get('iemi'))
                            +getStringValue(mo.get('outdoor_no'));

            ttiMap.put(onlykey,null );
            if(nccode != null &&  nccode != '')prodMap.put(nccode,'');

        }

        for ( TaskTrackingImport__c tti : [select Id ,MCode__c,Only__c from TaskTrackingImport__c where MCode__c in: mcodeMap.keySet() or Only__c in:ttiMap.keySet() ]) {
            mcodeMap.put(tti.MCode__c, tti.Id );
            ttiMap.put(tti.Only__c,tti);
        }

        for(Product__c p :[select Id ,NCCode__c,Name,ProductName__c from Product__c where NCCode__c in: prodMap.keySet()]){
            prodMap.put(p.NCCode__c, p.Id);
            prodNameMap.put(p.NCCode__c, p.ProductName__c == null ? p.Name : p.ProductName__c );
        }
       
        Map<String ,String> comMap = new Map<String,String>();
        for(String com : Label.ShortCompanyName.split(',',-1)){
            List<String> cs = com.split('-',-1);
            if(cs != null && cs.size() > 1)comMap.put(cs[1],cs[0]);
        }
        comMap.put('东区','MKSW');
        comMap.put('南区','MKSW' );
        comMap.put('西区','MKSW' );
        comMap.put('北区','MKSW' );
        comMap.put('中区','MKSW' );



        List<TaskTrackingImport__c> impList = new List<TaskTrackingImport__c>();
        List<TaskTrackingDetailImport__c> d_implist  = new List<TaskTrackingDetailImport__c>();
        Set<String> onlykeys = new Set<String>();
        Map<String,String> pTypeMap = getPicklistValues('Account','MKCooperationType__c',true);
        for(Object o : cList){
            Map<String,Object> mo = (Map<String,Object>)o;

            try{

                if( mo.get('mcode') == null )new DmlException('识别码必填!');

                //{
                //     mo.put('msg','识别码必填!' );
                //     errList.add(mo);
                //     continue;
                // }

                if(mcodeMap.get(getStringValue(mo.get('mcode'))) != null )new DmlException('已存在该识别码的数据,检查是否重复导入');
                // {
                //     mo.put('msg','已存在该识别码的数据,检查是否重复导入!'+getStringValue(mo.get('mcode')) );
                //     errList.add(mo);
                //     continue;
                // }
                if(getTTAccountID(getStringValue(mo.get('sf_ter_account_id'))) == null || getTTAccountID(getStringValue(mo.get('sf_pay_account_id'))) == null )new DmlException('SF开票客户ID 或者 SF终端客户ID错误!');
                // {
                //     mo.put('msg','SF开票客户ID 或者 SF终端客户ID错误!' );
                //     errList.add(mo);
                //     continue;
                // }
                

                Account acc1 =  [select Id ,MKCooperationType__c from Account where Id=: getTTAccountID(getStringValue(mo.get('sf_pay_account_id')))];
                
                if(pTypeMap.get(acc1.MKCooperationType__c)  !=getStringValue(mo.get('coop_type')) )new DmlException('项目合作类型与开票客户项目合作类型与不一致!');
                // {

                //     mo.put('msg', '项目合作类型与开票客户项目合作类型与不一致!');
                //     errList.add(mo);
                //     continue;
                // }

                if(!comMap.containsKey(getStringValue(mo.get('sign_company'))))new DmlException('子公司(签约公司) 填写错误!');
                // {
                //     mo.put('msg','子公司(签约公司) 填写错误!');
                //     errList.add(mo);
                //     continue;
                // }
                if(!comMap.containsKey(getStringValue(mo.get('owner_area'))))new DmlException('归属公司(大区/子公司) 填写错误!');
                // {
                //     mo.put('msg','归属公司(大区/子公司) 填写错误!');
                //     errList.add(mo);
                //     continue;
                // }


                 String onlykey = getTTAccountID(getStringValue(mo.get('sf_ter_account_id')))
                            +getTTAccountID(getStringValue(mo.get('sf_pay_account_id')))
                            +getStringValue(mo.get('owner_area'))
                            +getStringValue(mo.get('owner_year_month'))
                            +getStringValue(mo.get('sign_company'))
                            +getStringValue(mo.get('regent_brand'))
                            +getStringValue(mo.get('regent_cate1'))
                            +getStringValue(mo.get('regent_cate2'))
                            +getStringValue(mo.get('nccode'))
                            +getStringValue(mo.get('iemi'))
                            +getStringValue(mo.get('outdoor_no'));

                if(ttiMap.get(onlykey) != null )new DmlException('数据可能存在重复,请核实!组合键为:'+onlykey + '重复的识别码:'+ ttiMap.get(onlykey).MCode__c );
                // {
                //     mo.put('msg','数据可能存在重复,请核实!组合键为:'+onlykey + '重复的识别码:'+ ttiMap.get(onlykey).MCode__c );
                //     errList.add(mo);
                // }
                TaskTrackingImport__c tti = new TaskTrackingImport__c();
                tti.Outgoingway__c = getStringValue(mo.get('outdoor_way'));
                tti.EnterWay__c = getStringValue(mo.get('enter_way'));
                
                tti.TaskSource__c = getStringValue(mo.get('task_resource'));

                if(String.isBlank(tti.TaskSource__c))new DmlException('任务量来源不能为空!');
                // {
                //     mo.put('msg','任务量来源不能为空!');
                //     errList.add(mo);
                //     continue;
                // }
                tti.OutgoingNumber__c = getStringValue(mo.get('outdoor_no'));

                tti.EquipNote__c = getStringValue(mo.get('equip_note'));
                tti.TaskDetailNote__c = getStringValue(mo.get('detail_note'));

               // tti.IsTridFromContract__c = getStringValue(mo.get('is_trid_from_contract'));
                tti.RegentBrand__c = getStringValue(mo.get('regent_brand'));

                String prodId = prodMap.get(getStringValue(mo.get('nccode'))) ;
                if((prodId ==  null ||  prodId == '') && getStringValue(mo.get('nccode')) != null &&  getStringValue(mo.get('nccode')) != '' )new DmlException('仪器未匹配到产品:'+getStringValue(mo.get('nccode')));
                // {
                //     mo.put('msg','仪器未匹配到产品:'+getStringValue(mo.get('nccode')));
                //     errList.add(mo);
                //     continue;

                // }

                tti.InstrumentName__c = prodId== null ||  prodId == '' ? null : prodId ;

                if(tti.InstrumentName__c != null && (prodNameMap.get(getStringValue(mo.get('nccode'))) != getStringValue(mo.get('invname')) )  )new DmlException('仪器名称不一致 请核实数据是否有误:'+getStringValue(mo.get('invname')) +'==='+ prodNameMap.get(getStringValue(mo.get('nccode'))));
                // {
                //     mo.put('msg','仪器名称不一致 请核实数据是否有误:'+getStringValue(mo.get('invname')) +'==='+ prodNameMap.get(getStringValue(mo.get('nccode'))));
                //     errList.add(mo);
                //     continue;
                // }


                tti.SerialNo__c = getStringValue(mo.get('iemi'));
                tti.Numberofyears__c = getStringValue(mo.get('coop_year'));

                tti.InstrumentType__c = getStringValue(mo.get('invtype'));//仪器规格型号
                tti.Mcode__c = getStringValue(mo.get('mcode'));//识别码
                Boolean is_d  = false;
                try {

                    if(tti.Mcode__c  != null ) {
                        Decimal t_d = Decimal.valueOf(tti.MCode__c);
                        is_d = true; 
                    }
                }catch (Exception e) { }
                if(is_d)throw new DmlException('导入识别码不能是纯数字!');

                tti.Enddateofinstrument__c = getDateValue(mo.get('coop_end_date'));
                if(tti.Enddateofinstrument__c == null)throw new DmlException('合作截止日期格式错误! 格式为:yyyy-MM-dd');
                // {
                //     mo.put('msg','合作截止日期格式错误! 格式为:yyyy-MM-dd');
                //     errList.add(mo);
                //     continue;
                // }

                tti.Instrumentstartdate__c = getDateValue(mo.get('coop_start_date'));
                if(tti.Enddateofinstrument__c == null)throw new DmlException('合作起算日期格式错误! 格式为:yyyy-MM-dd');
                // {
                //     mo.put('msg','合作起算日期格式错误! 格式为:yyyy-MM-dd');
                //     errList.add(mo);
                //     continue;
                // }

                 Decimal coopYs  = 0;
               try {


                     coopYs = Decimal.valueOf(tti.Numberofyears__c);
                   // System.debug(String.valueOf(coopYs* 12) +'====' +String.valueOf(tti.Instrumentstartdate__c.monthsBetween(tti.Enddateofinstrument__c) +1));
                    
                    // {
                    //     mo.put('msg','合作起止日期与合作年限不匹配');
                    //     errList.add(mo);
                    //     continue;
                    // } 
                   
               }catch (Exception e) {
                    // mo.put('msg','合作年限格式不对,请只填数字!');
                    // errList.add(mo);
                    // continue;
                    throw new DmlException('合作年限格式不对,请只填数字!');
               }
               if(coopYs == 0) throw new DmlException('合作年限必填,请只填数字!');
               if(tti.Instrumentstartdate__c.monthsBetween(tti.Enddateofinstrument__c) +1 != Integer.valueOf(coopYs * 12))new DmlException('合作起止日期与合作年限不匹配');
                Integer endy = tti.Enddateofinstrument__c.year();
                boolean isnerr  = false;
                for(Integer i = endy+1 ; i < endy+10; i ++){

                    if(mo.get('assign_'+i) != null   ){

                        isnerr = true; 
                        break;
                    }
                }
                if(isnerr)throw new DmlException('任务量超出合作截止日期!');
                // {
                //     mo.put('msg','任务量超出合作截止日期!');
                //     errList.add(mo);
                //     continue;
                // }
               

                
               /* tti.AllBrand__c = getBooleanValue(mo.get('is_all_brand'));
                tti.AllMaccuraBrand__c =  getBooleanValue(mo.get('is_all_maccura_brand'));
                if(tti.AllBrand__c == null ){
                    mo.put('msg','是否取全品牌 只能填写"是" 或 "否" ');
                    errList.add(mo);
                    continue;
                }
                if(tti.AllMaccuraBrand__c == null ){
                    mo.put('msg','是否取迈克全品牌 只能填写"是" 或 "否" ');
                    errList.add(mo);
                    continue;
                }*/

                tti.ContractYear__c = getStringValue(mo.get('contract_year'));
                tti.MKCooperationType__c = getStringValue(mo.get('coop_type'));
                tti.ContractStartDate__c =  getDateValue(mo.get('contract_start_date'));
                tti.ContractEndDate__c =  getDateValue(mo.get('contract_end_date'));

                tti.Company__c = comMap.get(getStringValue(mo.get('sign_company')));
                tti.OwnerCompany__c = getStringValue(mo.get('owner_area'));
                tti.OwnerYM__c = getStringValue(mo.get('owner_year_month'));
                tti.SubcompanyInstrumentDeliveryCost__c = getDecimalValue(mo.get('sub_cost'));
                tti.InstrumentDeliveryCost__c = getDecimalValue(mo.get('group_cost'));
                tti.OverallPackagingMode__c = getStringValue(mo.get('pack_way'));
                tti.Contract__c = getStringValue(mo.get('is_have_contract'));
                tti.CalculationTable__c = getStringValue(mo.get('is_have_mc'));
                tti.ContractNumber__c = getStringValue(mo.get('contract_no'));


                
                tti.OutdoorDate__c = getDateValue(mo.get('outdoor_date')); 

                tti.Account__c =  getStringValue(mo.get('sf_pay_account_id'));
                Map<String,String> cM = ImportObject.getPicklistValues('Contract__c','Corpcode__c',true);


                /*Account acc = [select Id,Name , Owner.subcompany__c from Account where Id =:tti.Account__c ];
                if( cM.get(comMap.get(tti.OwnerCompany__c)) != acc.Owner.subcompany__c){
                    mo.put('msg',acc.Name +'归属公司 与 开票客户所属公司不一致! 开票客户所属公司:'+acc.Owner.subcompany__c );
                    errList.add(mo);

                    continue;
                }*/


                tti.TerminalCustomer__c = getStringValue(mo.get('sf_ter_account_id'));
                tti.EstimateNumber__c = getStringValue(mo.get('sf_mc_no'));
                tti.Only__c = onlykey; //getStringValue(mo.get('owner_year_month'));

                String cate1 = getStringValue(mo.get('regent_cate1')); 
                String cate2 = getStringValue(mo.get('regent_cate2')); 
                String brand = getStringValue(mo.get('regent_brand')); 
                String isadd = getStringValue(mo.get('is_need_add_task'));
                String iscover  = getStringValue(mo.get('is_need_replace_task'));

                 ///查找测算
                String mc_no = null;
                if(tti.EstimateNumber__c != null  && tti.EstimateNumber__c.trim() != ''){

                    try {
                       mc_no =  [select Name  from Measure_Calculate__c where name =: tti.EstimateNumber__c.trim() ].Name ;
                    }
                    catch (Exception e) {
                        throw new DmlException('测算编号不存在!'+tti.EstimateNumber__c);
                        // mo.put('msg', '测算编号不存在!'+tti.EstimateNumber__c);
                        // errList.add(mo);
                        // continue;
                         
                    }
                    
                } 
                if(cate1 == null || cate2 == null || brand == null)throw new DmlException('追踪试剂 一级分类 二级分类 品牌 必填!');
                // {
                //     mo.put('msg', '追踪试剂 一级分类 二级分类 品牌 必填!');
                //     errList.add(mo);
                //     continue;
                // }

                Integer y = System.now().year() + 16;
                

                for(Integer i = 2010 ; i < y ; i ++){
                    TaskTrackingDetailImport__c ttdi = new TaskTrackingDetailImport__c();
                    String year = String.valueOf(i);
                    if(mo.get('assign_'+year) == null   )continue;
                    ttdi.MCode__c = getStringValue(mo.get('mcode'));
                    ttdi.SubCompanyGrossProfit__c = getDecimalValue(mo.get('sub_profit_'+year));
                    ttdi.Years__c = year;
                    ttdi.WhetherNew__c= isadd;
                    ttdi.WhetherCovered__c = iscover;
                    ttdi.Classification1__c = cate1;
                    ttdi.Classification2__c = cate2;
                    ttdi.ReagentBrand__c = brand ;
                    ttdi.ReagentAssignments__c  = getDecimalValue(mo.get('assign_'+year));
                    if(ttdi.ReagentAssignments__c == null) continue;
                    ttdi.GroupGrossProfit__c = getDecimalValue(mo.get('group_profit_'+year)); 
                    d_implist.add(ttdi);
                }
                impList.add(tti);
            }catch(Exception e){
                mo.put('msg','数据转换错误!'+ e.getMessage() +'  '+e.getStackTraceString());
                errList.add(o);

            }
            
        }

        SavePoint sp = Database.setSavepoint();
       try{
           if(impList.size() > 0){
                insert impList ;  
               Map<String,String> tMap = new Map<String,String>();
               System.debug(impList);
               for(TaskTrackingImport__c tti : impList){
                    tMap.put(tti.Mcode__c,tti.Id);
               }
               for(TaskTrackingDetailImport__c ttdi : d_implist){
                    ttdi.TaskTrackingImport__c = tMap.get(ttdi.Mcode__c);
               }
               System.debug(d_implist);
                List<TaskTrackingDetailImport__c > deleList = [select Id from TaskTrackingDetailImport__c where  TaskTrackingImport__c in: tMap.values()];
                if(deleList.size() > 0) delete deleList;
               if(d_implist.size()> 0) insert  d_implist ; 
            }
       }catch(Exception e ){
            Database.rollback(sp);

            for(Object o : cList){
                Map<String,Object> mo = (Map<String,Object>) o;
                mo.put('msg', '保存失败!'+e.getMessage() + '  '+ e.getStackTraceString());
            }
            errList.clear();
            errList.addAll(cList);
       } 

       resultMap.put('errData',errList);
       resultMap.put('code',1);

       return EncodingUtil.urlEncode(JSON.serialize(resultMap), 'UTF-8') ;
       

    }
    public static Boolean getBooleanValue(Object o){
        if(o == null) return null;
        if(getStringValue(o) == '是')return true;
        if(getStringValue(o) == '否')return false;
        return null;
    }
    public static Date getDateValue(Object o ){
        if(o == null) return null;
        try{
            return Date.valueOf(String.valueOf(o).trim());
        }catch(Exception e){
            return null;
        }
    }
    public static Decimal getDecimalValue(Object o){
        if(o == null)return null;
        String d = String.valueOf(o).trim();
        if(d == '')return null;
        return Decimal.valueOf(d);
    }
    public static String  getTTAccountID(String accid){
        if(accid == null )return null ;
        try{
            return String.valueOf(Id.valueOf(accid));
        }catch(Exception e){
            return null;
        }
    }
    public static String getStringValue(Object o){
        if(o == null)return null;
        return String.valueOf(o).trim();
    }

    /*
    * company : 公司编码
    * c : 存货编码
    * accId : 客户id 
    * parentId : 母公司Id
    * terminId : 终端Id 
    * salescode : 归属公司
    */
    @RemoteAction
    public static List<ReturnProduct> matchProduct(String company ,String c ,String province, String accId ,String parentId,String terminalId ,String salescode ){

        if(c == null) return null;
        List<Object> cList = (List<Object>) JSON.deserializeUntyped(c);
        if(cList == null || cList.size() == 0) return null;
        Set<String> codes = new Set<String>();
        for (Object o: cList) {
            if(o == null)continue;

            codes.add(String.valueOf(o).trim());
        }
        if(cList.size() == 0) return null;
        String companycode = getPicklistValues('Contract__c','Corpcode__c',false).get(company);
        String sealflag  =  'Y-'+ companycode;
        //找出产品
        Map<String ,Product__c> productMap  = new Map<String,Product__c>();
        Account acc = [select Id, Name ,System__c from Account where Id=:accId];
        Boolean isBM = acc.System__c == '大家检验';
       
        for(Product__c p: isBM ?[select Id,Name ,NCCode__c,Brand__c ,Spec__c,SerialNo__c,Model__c,zl__c,Category0__c,
            Category1__c,Category2__c,Category3__c,TypeName__c,swjhdj__c,TestNumber__c,
            SealCompany__c from Product__c where NCCode__c in: codes  and RecordType.DeveloperName = 'NCProduct'  and Brand__c not in:MaccuraBrandUtil.maccura and NCCode__c not in:MaccuraBrandUtil.maccura  ]  : [select Id,Name ,NCCode__c,Brand__c ,Spec__c,SerialNo__c,Model__c,zl__c,Category0__c,
            Category1__c,Category2__c,Category3__c,TypeName__c,swjhdj__c,TestNumber__c,
            SealCompany__c from Product__c where NCCode__c in: codes  and RecordType.DeveloperName = 'NCProduct'  ]){
            productMap.put(p.NCCode__c, p);
        }   
        Boolean ist  = isThrid(acc);      
        ///找出价格体系
        Map<String ,Price__c> priceMap = ist?  getPriceMap(codes, company,false):    getPriceMap(codes, company,province,false);

        //上月平均价(元)
         Map<String ,AveragePrice__c>lastPs = getLastMothPrice(codes, company,province);
         //价目表价格
         Map<String,PriceList__c> PriceListMap = new Map<String,PriceList__c>();
        if(accId != null) PriceListMap = getPriceListMap(codes, accId,terminalId ,salescode,company,false);
        ///体系价目表价格
        Map<String,PriceList__c> sysPriceListMap = new Map<String,PriceList__c>();
        if(parentId != null) sysPriceListMap = getPriceListMap(codes, parentId,salescode,company,true);

        List<ReturnProduct> rpList = new List<ReturnProduct>();
        
        //组装并返回结果
        for (String code : codes) {
            ReturnProduct rp = new ReturnProduct(productMap.get(code),priceMap.get(code),lastPs.get(code),PriceListMap.get(code),sysPriceListMap.get(code),code,company,sealflag);
            rpList.add(rp);
        }
        return rpList;

    }
    /*
    * company : 公司编码
    * codes : 存货编码
   
     @RemoteAction
    public static List<ReturnProduct> matchProduct(String company ,String c , String accId ,String parentId ,String salescode ){

    	if(c == null) return null;
    	List<Object> cList = (List<Object>) JSON.deserializeUntyped(c);
    	if(cList == null || cList.size() == 0) return null;
    	Set<String> codes = new Set<String>();
    	for (Object o: cList) {
            if(o == null)continue;

    		codes.add(String.valueOf(o).trim());
    	}
    	if(cList.size() == 0) return null;
    	String companycode = getPicklistValues('Contract__c','Corpcode__c',false).get(company);
    	String sealflag  =  'Y-'+ companycode;
    	//找出产品
    	Map<String ,Product__c> productMap  = new Map<String,Product__c>();

		for(Product__c p:[select Id,Name ,NCCode__c,Brand__c ,Spec__c,SerialNo__c,Model__c,zl__c,Category0__c,
    		Category1__c,Category2__c,Category3__c,TypeName__c,swjhdj__c,TestNumber__c,
    		SealCompany__c from Product__c where NCCode__c in: codes  and RecordType.DeveloperName = 'NCProduct'  ]){
    		productMap.put(p.NCCode__c, p);
    	}   	
    	///找出价格体系
    	Map<String ,Price__c> priceMap = getPriceMap(codes, company);

        //上月平均价(元)
         Map<String ,AveragePrice__c>lastPs = getLastMothPrice(codes, company);
         //价目表价格
         Map<String,PriceList__c> PriceListMap = new Map<String,PriceList__c>();
    	if(accId != null) PriceListMap = getPriceListMap(codes, accId ,salescode,false);
    	///体系价目表价格
    	Map<String,PriceList__c> sysPriceListMap = new Map<String,PriceList__c>();
    	if(parentId != null) sysPriceListMap = getPriceListMap(codes, parentId,salescode,true);

    	List<ReturnProduct> rpList = new List<ReturnProduct>();
    	
    	//组装并返回结果
    	for (String code : codes) {
    		ReturnProduct rp = new ReturnProduct(productMap.get(code),priceMap.get(code),lastPs.get(code),PriceListMap.get(code),sysPriceListMap.get(code),code,company,sealflag);
    		rpList.add(rp);
    	}
    	return rpList;

    } */

    //是否为第三方客户
    private static boolean isThrid(Account acc ){
        if(acc == null)return false;
        if(acc.System__c != null) return true;
        return false;
    }
    @RemoteAction
    public static List<ReturnProduct> matchProductNo(String company ,String c,String province , String accId  ,String salescode ,String terminalId ,Boolean isParent ){

        if(c == null) return null;
        List<Object> cList = (List<Object>) JSON.deserializeUntyped(c);
        if(cList == null || cList.size() == 0) return null;
        Set<String> codes = new Set<String>();
        for (Object o: cList) {
            if(o == null)continue;
            codes.add(String.valueOf(o).trim());
        }
        if(cList.size() == 0) return null;
        String companycode = getPicklistValues('Contract__c','Corpcode__c',false).get(company);
        String sealflag  =  'Y-'+ companycode;

        //找出产品
        Map<String ,Product__c> productMap  = new Map<String,Product__c>();

        for(Product__c p:[select Id,Name ,NCCode__c,Brand__c ,Spec__c,SerialNo__c,Model__c,zl__c,Category0__c,
            Category1__c,Category2__c,Category3__c,TypeName__c,swjhdj__c, TestNumber__c,

            SealCompany__c from Product__c where NCCode__c in: codes  and RecordType.DeveloperName = 'NCProduct'  ]){
            productMap.put(p.NCCode__c, p);
        }  
        Account acc = [select Id, System__c from Account where Id=:accId];
        Boolean ist = isThrid(acc);     
        ///找出价格体系
        Map<String ,Price__c> priceMap = ist ?  getPriceMap(codes, company,false): getPriceMap(codes, company,province,false );
         //价目表价格
         Map<String,PriceList__c> PriceListMap = new Map<String,PriceList__c>();
        if(accId != null) PriceListMap = getPriceListMap(codes, accId ,terminalId,salescode,company,isParent);

        List<ReturnProduct> rpList = new List<ReturnProduct>();
        
        //组装并返回结果
        for (String code : codes) {
            ReturnProduct rp = new ReturnProduct(productMap.get(code),priceMap.get(code),code,company,PriceListMap.get(code),sealflag);
            rpList.add(rp);
        }
        return rpList;

    }


     /*
		psets : 产品ID 
		company : 公司名称 
    */
    //获取价格体系价格
     public static Map<Id,Price__c> getPriceMap(Set<Id> psets,String company,String province, boolean isOversea  ){
        Map<Id ,Price__c> cp_prs = new Map<Id,Price__c>();
         // if(String.isBlank(province) || !company.contains('上海')) province = null;
        for (Price__c p : [select Province__c,Product__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,Subsidiary_price__c,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,
                           SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                           GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c 
                           from Price__c where Product__c in: psets and Company__c =:company and ClosePrice__c != true and Province__c=:province]){
                 

              //如果不是海外 省份 是海外 跳过
                 if(!isOversea &&  p.Province__c == '海外')continue;
                //如果是海外 省份不是海外 跳过
                 if(isOversea &&  p.Province__c != '海外')continue;
                 cp_prs.put(p.Product__c,p); 
           
        }  
            return cp_prs;
    }

    public static Map<String,Price__c> getPriceMap(Set<String> psets,String company,String province , boolean isOversea ){
        Map<String ,Price__c> cp_prs = new Map<String,Price__c>();
        // if(String.isBlank(province) || !company.contains('上海')) province = null;
        for (Price__c p : [select Province__c,Product__c,Product__r.NCCode__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,
                            SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                             GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c ,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,Subsidiary_price__c
                           from Price__c where Product__r.NCCode__c in: psets and Company__c =:company and ClosePrice__c != true and Province__c=: province ]){
                 

              //如果不是海外 省份 是海外 跳过
                 if(!isOversea &&  p.Province__c == '海外')continue;
                //如果是海外 省份不是海外 跳过
                 if(isOversea &&  p.Province__c != '海外')continue;
                 cp_prs.put(p.Product__r.NCCode__c,p);  
           
        }  
        return cp_prs;
    }

    public static Map<Id,Price__c> getPriceMap(Set<Id> psets,String company,String province ){
        Map<Id ,Price__c> cp_prs = new Map<Id,Price__c>();
         // if(String.isBlank(province) || !company.contains('上海')) province = null;
        for (Price__c p : [select Province__c,Product__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,Subsidiary_price__c,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,
                           SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                           GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c 
                           from Price__c where Product__c in: psets and Company__c =:company and ClosePrice__c != true and Province__c=:province]){
                 cp_prs.put(p.Product__c,p);  

           
        }  
            return cp_prs;
    }

    public static Map<String,Price__c> getPriceMap(Set<String> psets,String company,String province ){
        Map<String ,Price__c> cp_prs = new Map<String,Price__c>();
        // if(String.isBlank(province) || !company.contains('上海')) province = null;
        for (Price__c p : [select Province__c, Product__c,Product__r.NCCode__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,
                            SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                             GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c ,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,Subsidiary_price__c
                           from Price__c where Product__r.NCCode__c in: psets and Company__c =:company and ClosePrice__c != true and Province__c=: province ]){
                 cp_prs.put(p.Product__r.NCCode__c,p);  
           
        }  
            return cp_prs;
    }

    ///获取价格体系价格
    public static Map<Id,Price__c> getPriceMap(Set<Id> psets,String company){
    	Map<Id ,Price__c> cp_prs = new Map<Id,Price__c>();
        //User u = [select Province__c from User where Id =:UserInfo.getUserId()];
        // and Province__c=:u.Province__c
        for (Price__c p : [select Province__c, Product__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,Subsidiary_price__c,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,
                           SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                           GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c 
                           from Price__c where Product__c in: psets and Company__c =:company and ClosePrice__c != true]){
                 cp_prs.put(p.Product__c,p);  
           
        }  
          	return cp_prs;
    }

    public static Map<String,Price__c> getPriceMap(Set<String> psets,String company){
       // User u = [select Province__c from User where Id =:UserInfo.getUserId()];
        //and Province__c=:u.Province__c 
        Map<String ,Price__c> cp_prs = new Map<String,Price__c>();
        for (Price__c p : [select Province__c,Product__c,Product__r.NCCode__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,
                            SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                             GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c ,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,Subsidiary_price__c
                           from Price__c where Product__r.NCCode__c in: psets and Company__c =:company and ClosePrice__c != true ]){
                 cp_prs.put(p.Product__r.NCCode__c,p);  
           
        }  
            return cp_prs;
    }

     ///获取价格体系价格
    public static Map<Id,Price__c> getPriceMap(Set<Id> psets,String company, boolean isOversea ){
        Map<Id ,Price__c> cp_prs = new Map<Id,Price__c>();
        //User u = [select Province__c from User where Id =:UserInfo.getUserId()];
        // and Province__c=:u.Province__c

        for (Price__c p : [select Product__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,Subsidiary_price__c,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,
                           SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,Province__c,
                           GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c 
                           from Price__c where Product__c in: psets and Company__c =:company and ClosePrice__c != true]){
                 
                 //如果不是海外 省份 是海外 跳过
                 if(!isOversea &&  p.Province__c == '海外')continue;
                //如果是海外 省份不是海外 跳过
                 if(isOversea &&  p.Province__c != '海外')continue;
                cp_prs.put(p.Product__c,p); 
                 
           
        }  
            return cp_prs;
    }
     public static Map<String,Price__c> getPriceMap(Set<String> psets,String company, boolean isOversea){

    	Map<String ,Price__c> cp_prs = new Map<String,Price__c>();
        for (Price__c p : [select Product__c,Product__r.NCCode__c,Company__c,CompanyBottomPrice__c,HospitalBottomPrice__c,Taxrate__c,
                            SalesmanPrice__c,SalesDirectorPrice__c,SalesManagerPrice__c,SpecialPrice__c,ProvincialAgencyPrice__c,
                             GroupTerminalGuidePrice__c,GroupDeclarationDealerPrice__c,GroupRegionalDistributorsPrice__c ,Province__c,
                           InvoiceDealerPrice__c,MarketPriceUSD__c,AreaDealerPrice__c,MarketPrice__c,HospitalManagerPrice__c,InstCost__c,RepairCost__c,Subsidiary_price__c
                           from Price__c where Product__r.NCCode__c in: psets and Company__c =:company and ClosePrice__c != true ]){
             //如果不是海外 省份 是海外 跳过
                 if(!isOversea &&  p.Province__c == '海外')continue;
                //如果是海外 省份不是海外 跳过
                 if(isOversea &&  p.Province__c != '海外')continue;
                 cp_prs.put(p.Product__r.NCCode__c,p);  
           
        }  
          	return cp_prs;
    }

    /*
		psets : 产品ID 
		company : 公司名称 
    */
    ///获取上月平均价
    public static  Map<Id,AveragePrice__c> getLastMothPrice(Set<Id> psets,String company){
    	 /// 日期处理
        Integer m = Date.today().month(); //当前月份
        Integer y = Date.today().year();  //当前年份 
       ///取上月
         if(m == 1){
            m = 12 ;
            y -= 1;
        }else{
            m -= 1;
            
        }
        
        String  month = String.valueOf(m) + '月';
        String  year= String.valueOf(y) + '年';
        //上月平均价(元)
         Map<Id ,AveragePrice__c>lastPs = new Map<Id ,AveragePrice__c>();
         for(AveragePrice__c a : [select Id,AveragePrice__c  ,Product__c from AveragePrice__c where 
                                  Year__c =:year and Month__c =: month and Product__c in : psets and Company__c=:company and AveragePrice__c != null ]){
                     lastPs.put( a.Product__c,a);  
         }
    	return lastPs;
    }
     public static  Map<Id,AveragePrice__c> getLastMothPrice(Set<Id> psets,String company,String province){
         /// 日期处理
        Integer m = Date.today().month(); //当前月份
        Integer y = Date.today().year();  //当前年份 
       ///取上月
         if(m == 1){
            m = 12 ;
            y -= 1;
        }else{
            m -= 1;
            
        }
        
        String  month = String.valueOf(m) + '月';
        String  year= String.valueOf(y) + '年';
        //上月平均价(元)
         Map<Id  ,AveragePrice__c>lastPs = new Map<Id  ,AveragePrice__c>();
         for(AveragePrice__c a : [select Id,AveragePrice__c ,Product__r.NCCode__c ,Product__c from AveragePrice__c where 
                                  Year__c =:year and Month__c =: month and Product__c in : psets and Company__c=:company and AveragePrice__c != null and PriceProvince__c =:province ]){
                     lastPs.put( a.Product__c,a);  
         }
        return lastPs;
    }
    public static  Map<String,AveragePrice__c> getLastMothPrice(Set<String> psets,String company,String province){
         /// 日期处理
        Integer m = Date.today().month(); //当前月份
        Integer y = Date.today().year();  //当前年份 
       ///取上月
         if(m == 1){
            m = 12 ;
            y -= 1;
        }else{
            m -= 1;
            
        }
        
        String  month = String.valueOf(m) + '月';
        String  year= String.valueOf(y) + '年';
        //上月平均价(元)
         Map<String  ,AveragePrice__c>lastPs = new Map<String ,AveragePrice__c>();
         for(AveragePrice__c a : [select Id,AveragePrice__c ,Product__r.NCCode__c ,Product__c from AveragePrice__c where 
                                  Year__c =:year and Month__c =: month and Product__r.NCCode__c in : psets and Company__c=:company and AveragePrice__c != null and PriceProvince__c =:province ]){
                     lastPs.put( a.Product__r.NCCode__c,a);  
         }
        return lastPs;
    }
     public static  Map<String,AveragePrice__c> getLastMothPrice(Set<String> psets,String company){
    	 /// 日期处理
        Integer m = Date.today().month(); //当前月份
        Integer y = Date.today().year();  //当前年份 
       ///取上月
         if(m == 1){
            m = 12 ;
            y -= 1;
        }else{
            m -= 1;
            
        }
        
        String  month = String.valueOf(m) + '月';
        String  year= String.valueOf(y) + '年';
        //上月平均价(元)
         Map<String  ,AveragePrice__c>lastPs = new Map<String ,AveragePrice__c>();
         for(AveragePrice__c a : [select Id,AveragePrice__c ,Product__r.NCCode__c ,Product__c from AveragePrice__c where 
                                  Year__c =:year and Month__c =: month and Product__r.NCCode__c in : psets and Company__c=:company and AveragePrice__c != null ]){
                     lastPs.put( a.Product__r.NCCode__c,a);  
         }
    	return lastPs;
    }

    /*
		psets : 产品ID 
		accID : 客户id 
		salescode : 销售组织编码
    */
    ///获取价目表价格
    public static Map<Id,PriceList__c> getPriceListMap(Set<Id> psets ,String accId ,String salescode,String company ,Boolean isParent){

    	Map<Id,PriceList__c> pMap = new Map<Id,PriceList__c>();

    	if(accId == null) return pMap;
    	List<PriceList__c> plList = new List<PriceList__c>();
    	if(isParent) {
    		plList = [select Id,Product__c,Price__c ,SalesCode__c from PriceList__c where Account__c=:accId and Product__c in:psets];
    	}else{
    		plList = [select Id,Product__c,Price__c ,SalesCode__c from PriceList__c where Account__c=:accId and SalesCode__c=:salescode and Company__c=:company  and Product__c in:psets];
    	}
    	
    	for (PriceList__c p: plList) {
    		pMap.put(p.Product__c, p);
    	}
    	return pMap;

    }
    /*
        psets : 产品ID 
        accID : 客户id 
        salescode : 销售组织编码
    */
    ///获取价目表价格
    public static Map<Id,PriceList__c> getPriceListMap(Set<Id> psets ,String accId ,String appAccId  ,String salescode,String company ,Boolean isParent){

        Map<Id,PriceList__c> pMap = new Map<Id,PriceList__c>();


        if(accId == null) return pMap;

         Boolean issame =  appAccId == null  ;

        if(!issame)issame = Id.valueOf(accId)  ==  Id.valueOf( appAccId);
        if(appAccId == null )appAccId = accId;

        List<PriceList__c> plList = new List<PriceList__c>();
        if(isParent) {
            plList = [select Id,Product__c,Price__c ,SalesCode__c from PriceList__c where Account__c=:accId and Product__c in:psets];
        }else{
            if(issame)plList = [select Id,Product__c,Price__c ,SalesCode__c from PriceList__c where Account__c=:accId and SalesCode__c=:salescode and Product__c in:psets and (ApplicableCustomers__c =: appAccId or ApplicableCustomers__c = null )];
            if(!issame)plList = [select Id,Product__c,Price__c ,SalesCode__c from PriceList__c where Account__c=:accId and SalesCode__c=:salescode  and Company__c=:company  and Product__c in:psets and ApplicableCustomers__c =: appAccId ];
        }
        
        for (PriceList__c p: plList) {
            pMap.put(p.Product__c, p);
        }
        return pMap;

    }
     public static Map<String,PriceList__c> getPriceListMap(Set<String> psets ,String accId ,String salescode,String company ,Boolean isParent){

    	Map<String,PriceList__c> pMap = new Map<String,PriceList__c>();
		if(accId == null) return pMap;
		List<PriceList__c> plList = new List<PriceList__c>();
    	if(isParent) {
    		plList = [select Id,Product__c,Price__c ,Product__r.NCCode__c,SalesCode__c from PriceList__c where Account__c=:accId  and Product__r.NCCode__c in:psets];
    	}else{
    		plList = [select Id,Product__c,Price__c ,Product__r.NCCode__c,SalesCode__c from PriceList__c where Account__c=:accId and SalesCode__c=:salescode and Company__c=:company and Product__r.NCCode__c in:psets];
    	}
    	for (PriceList__c p: plList) {
    		pMap.put(p.Product__r.NCCode__c, p);
    	}
    	return pMap;

    }
     /*
     * appAccId//适用终端客户
     * accId //客户
     * psets 产品nccode 
     */
     public static Map<String,PriceList__c> getPriceListMap(Set<String> psets ,String accId,String appAccId  ,String salescode,String company ,Boolean isParent){

        Map<String,PriceList__c> pMap = new Map<String,PriceList__c>();
        if(accId == null) return pMap;

        Boolean issame =  appAccId == null  ;
        if(!issame)issame = Id.valueOf(accId)  ==  Id.valueOf( appAccId);
        if(appAccId == null )appAccId = accId;
        
        List<PriceList__c> plList = new List<PriceList__c>();
        if(isParent) {
            plList =[select Id,Product__c,Price__c ,Product__r.NCCode__c,SalesCode__c 
            from PriceList__c where Account__c=:accId  and Product__r.NCCode__c in:psets    ];
        }else{
            if(issame)plList = [select Id,Product__c,Price__c ,Product__r.NCCode__c,SalesCode__c from PriceList__c where Account__c=:accId and SalesCode__c=:salescode and Product__r.NCCode__c in:psets and (ApplicableCustomers__c =:appAccId or ApplicableCustomers__c = null )];

            if(!issame)plList = [select Id,Product__c,Price__c ,Product__r.NCCode__c,SalesCode__c from PriceList__c where Account__c=:accId and SalesCode__c=:salescode and Company__c=:company and Product__r.NCCode__c in:psets and ApplicableCustomers__c =:appAccId ];
        }
        for (PriceList__c p: plList) {
            pMap.put(p.Product__r.NCCode__c, p);
        }
        return pMap;

    }

    public static Map<String ,Product__c> getProudctMap(Set<String>nccodes ){
        Map<String ,Product__c> prduMap = new Map<String ,Product__c>();
        if(nccodes == null || nccodes.size() == 0) return prduMap;
        for(Product__c p:[select Id ,NCCode__c,Brand__c ,Model__c  from Product__c where NCCode__c in:nccodes]){
            prduMap.put(p.NCCode__c,p);
        }
        return prduMap;
    }
    //获得PickList的值 i
    public static Map<String, String> getPicklistValues(String sObjectName, String sFieldName,Boolean isReverse){
        Map<String, String> picValues= new Map<String, String>();
        Map<String, Schema.SObjectType> sObjectDescribeMap = Schema.getGlobalDescribe();
        if (sObjectDescribeMap.containsKey(sObjectName)) {
            Map<String, Schema.SobjectField> sObjectFieldsMap = 
               sObjectDescribeMap.get(sObjectName).getDescribe().fields.getMap();
            if (sObjectFieldsMap.containsKey(sFieldName)) {
                Schema.DescribeFieldResult sObjectFieldDescribe = sObjectFieldsMap.get(sFieldName).getDescribe();
                List<Schema.PicklistEntry> lPickEntryList = sObjectFieldDescribe.getPicklistValues();
                for (Schema.PicklistEntry tPicklistEntry : lPickEntryList) {
                    if(tPicklistEntry.isActive() == true){
                        if(isReverse == true ){
                        	picValues.put(tPicklistEntry.getValue(),tPicklistEntry.getLabel());
                        }else{
                        	picValues.put(tPicklistEntry.getLabel(),tPicklistEntry.getValue());
                        }
                    }
                    /*picValues.put(tPicklistEntry.getValue(), new Map<String,object>{
                        'value' => tPicklistEntry.getValue(),
                        'isActive' => tPicklistEntry.isActive(),
                        'isDefaultValue' => tPicklistEntry.isDefaultValue(),
                        'label' => tPicklistEntry.getLabel()
                    });*/
                }
            } else {
                //TODO 不存在此字段的执行
            }
        } else {
            // TODO 不存在此sObject的执行
        }
        return picValues;
    }
    public static Map<String,String> getObjectFields (String sObjectName,Boolean isReverse){
        if(sObjectName == null)return null;
        String objName =  sObjectName.trim().toLowerCase();
        Map<String,SObjectType> objMap =  Schema.getGlobalDescribe();
        SObjectType obj = objMap.get(objName);
        Map<String,String >fieldsMap = new Map<String,String>();
        for(Schema.SObjectField f :obj.getDescribe().fields.getMap().values()){
            if(isReverse){
                fieldsMap.put(f.getDescribe().getName(),f.getDescribe().getLabel());
            }else{
                fieldsMap.put(f.getDescribe().getLabel(),f.getDescribe().getName());
            }
         }
         return fieldsMap;
    }
    ///获取某一个对象的所有字段
    @RemoteAction
    public static String getObjectFieldsJSON(String sObjectName,Boolean isReverse){
        Map<String,String >fieldsMap = getObjectFields(sObjectName,isReverse);
        if(fieldsMap == null)return null;
        return EncodingUtil.urlEncode(JSON.serialize(fieldsMap), 'UTF-8') ;
    }

}